# 元组和列表同属序列类型，且都可以按照特定顺序存放一组数据，数据类型不受限制，只要是 Python 支持的数据类型就可以。那么，元组和列表有哪些区别呢？
#
# 元组和列表最大的区别就是，列表中的元素可以进行任意修改，就好比是用铅笔在纸上写的字，写错了还可以擦除重写；而元组中的元素无法修改，除非将元组整体替换掉，就好比是用圆珠笔写的字，写了就擦不掉了，除非换一张纸。
# 可以理解为，tuple 元组是一个只读版本的 list 列表。
#
# 需要注意的是，这样的差异势必会影响两者的存储方式，我们来直接看下面的例子：
# >>> listdemo = []
# >>> listdemo.__sizeof__()
# 40
# >>> tupleDemo = ()
# >>> tupleDemo.__sizeof__()
# 24
#
# 可以看到，对于列表和元组来说，虽然它们都是空的，但元组却比列表少占用 16 个字节，这是为什么呢？
#
# 事实上，就是由于列表是动态的，它需要存储指针来指向对应的元素（占用 8 个字节）。另外，由于列表中元素可变，所以需要额外存储已经分配的长度大小（占用 8 个字节）。
# 但是对于元组，情况就不同了，元组长度大小固定，且存储元素不可变，所以存储空间也是固定的。
#
# 读者可能会问题，既然列表这么强大，还要元组这种序列类型干什么？
#
# 通过对比列表和元组存储方式的差异，我们可以引申出这样的结论，即元组要比列表更加轻量级，所以从总体上来说，元组的性能速度要由于列表。
#
# 另外，Python 会在后台，对静态数据做一些资源缓存。通常来说，因为垃圾回收机制的存在，如果一些变量不被使用了，Python 就会回收它们所占用的内存，返还给操作系统，以
# 便其他变量或其他应用使用。
#
# 但是对于一些静态变量（比如元组），如果它不被使用并且占用空间不大时，Python 会暂时缓存这部分内存。这样的话，当下次再创建同样大小的元组时，Python 就可以不用再向
# 操作系统发出请求去寻找内存，而是可以直接分配之前缓存的内存空间，这样就能大大加快程序的运行速度。
#
# 下面的例子，是计算初始化一个相同元素的列表和元组分别所需的时间。我们可以看到，元组的初始化速度要比列表快 5 倍。
# C:\Users\mengma>python -m timeit 'x=(1,2,3,4,5,6)'
# 20000000 loops, best of 5: 9.97 nsec per loop
# C:\Users\mengma>python -m timeit 'x=[1,2,3,4,5,6]'
# 5000000 loops, best of 5: 50.1 nsec per loop
#
# 当然，如果你想要增加、删减或者改变元素，那么列表显然更优。因为对于元组来说，必须得通过新建一个元组来完成。
#
# 总的来说，元组确实没有列表那么多功能，但是元组依旧是很重要的序列类型之一，元组的不可替代性体现在以下这些场景中：
#
#   元组作为很多内置函数和序列类型方法的返回值存在，也就是说，在使用某些函数或者方法时，它的返回值会元组类型，因此你必须对元组进行处理。
#   元组比列表的访问和处理速度更快，因此，当需要对指定元素进行访问，且不涉及修改元素的操作时，建议使用元组。
#   元组可以在映射（和集合的成员）中当做“键”使用，而列表不行。这会在后续章节中作详解介绍。
